package core.util;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import core.modules.base.entity.SysUser;
import core.modules.base.service.SysMenuService;
import core.modules.base.service.SysUserService;

public class MyRealm extends AuthorizingRealm {
	@Autowired
	SysUserService sysUserService;
	@Autowired
	SysMenuService sysMenuService;

	// 通过用户名字找角色
	ConcurrentHashMap<String, String> usernameRoleMap;

	// 通过角色找权限
	ConcurrentHashMap<String, SimpleAuthorizationInfo> roleAuthorizationInfoMap;

	public MyRealm() {
		usernameRoleMap = new ConcurrentHashMap<String, String>();
		roleAuthorizationInfoMap = new ConcurrentHashMap<String, SimpleAuthorizationInfo>();
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		SysUser user = (SysUser) arg0.getPrimaryPrincipal();
		String username = user.getUsername();
		String roleid = usernameRoleMap.get(username);
		if (roleid != null) {
			return roleAuthorizationInfoMap.get(roleid);
		}
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) arg0;
		SysUser user = sysUserService.getDao()
				.getByInput(new SysUser(upToken.getUsername(), String.valueOf(upToken.getPassword())));
		if (user != null) {
			handlePermission(user.getId(), user.getUsername());
			if (user instanceof IPrincipal) {
				SimpleAuthenticationInfo s = new SimpleAuthenticationInfo(user, arg0.getCredentials(), getName());
				return s;
			}else {
				throw new AuthenticationException("登录对象必须实现core.util.IPrincipal接口");
			}
		} else {
			throw new AuthenticationException("密码错误");
		}
	}

	public void handlePermission(String uid, String username) {
		List<String> roles = sysUserService.getDao().getRoleIds(uid);
		for (String roleid : roles) {
			usernameRoleMap.put(username, roleid);
			List<String> permissions = sysMenuService.getDao().getPermission(roleid);
			if (WebUtil.isNotBlank(permissions)) {
				SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
				Set<String> stringPermissions = new HashSet<>();
				for (String perm : permissions) {
					if (WebUtil.isNotBlank(perm)) {
						stringPermissions.add(perm);
					}
				}
				simpleAuthorizationInfo.setStringPermissions(stringPermissions);
				roleAuthorizationInfoMap.put(roleid, simpleAuthorizationInfo);
			}
		}
	}
}
